

#include "platform.h"
#include "test_mode.h"
#include "logfile.h"
#include "cm_time.h"

#include "proto_plat.h"

#include "cm_fs.h"
//#include "bsp_4g.h"

#include "proto_upload_file.h"
#include "user_flash.h"





#define UPLOAD_PACKET_SIZE (1024)
#define UPLOAD_MAX_ERROR   (10)

typedef enum{
    upload_idle,
    upload_init,
    upload_pack,
    upload_send,
    upload_wait_ack,
    upload_finished,
}upload_state_e;

typedef struct{
    upload_state_e  state;
    uint8_t  retry;
    uint32_t file_num;
    uint32_t file_size;
    uint16_t total_packet;
    uint16_t current_packet;
    uint32_t send_time;
    int32_t  fd;
    int8_t   result;   //由uint8_t 改为 int8_t---dan
}upload_file_t;

upload_file_t upload_file={.state = upload_idle};


/**
 * @brief 对应上行0x11.
 * 
 * @param rxbuf 
 * @param txbuf 
 */
void logfile_upload_set(uint32_t file_num)
{
    memset(&upload_file,0,sizeof(upload_file));
    if(file_num < LOG_FILE_NUM)
    {
        upload_file.file_num = file_num;
        upload_file.state = upload_init;
        printf_log(lv2, "file upload init\n");
    }
}


/**
 * @brief 对应上行0x12
 * 
 * @param txbuf 

  txbuf = malloc(UPLOAD_PACKET_SIZE+32);
   free(txbuf);////debug -----导致内存泄漏-------

    // free(txbuf);////bug code -----导致内存泄漏-------

    if( NULL != txbuf )
    {
        free(txbuf);////debug -----导致内存泄漏-------
    }

 */
void logfile_upload_process(void)
{


#if 0  // =----有可能-导致内存泄漏---暂时屏蔽掉----



    static uint8_t* txbuf;
    static uint16_t txlen;
    
    switch(upload_file.state)
    {
    case upload_idle:
        return;

    case upload_init:
        upload_file.fd = cm_fs_open(logfile_get_name(upload_file.file_num),CM_FS_RB);
        if(upload_file.fd>=0)
        {

          //  upload_file.file_size = cm_fs_filesize(logfile_get_name(upload_file.file_num));
            upload_file.file_size = Flash_GetAppSize();    //dan

            upload_file.total_packet = upload_file.file_size / UPLOAD_PACKET_SIZE;
            if(upload_file.file_size % UPLOAD_PACKET_SIZE)upload_file.total_packet+=1;
            upload_file.current_packet = 1;

            txbuf = malloc(UPLOAD_PACKET_SIZE+32);   /////有可能导致内存泄漏
            if(txbuf == NULL)
            {
                upload_file.result = -1;
                printf_log(lv1, "upload file mem err!\n");
                break;
            }
            upload_file.state = upload_pack;
        }else{
            upload_file.retry++;
        }
        break;

    case upload_pack:
    {
        ptlv_t pf = (ptlv_t)txbuf;
        uint8_t* pbody = pf->data + sizeof(tlv_head_t);

        pbody[0] = (uint8_t)upload_file.total_packet;
        pbody[1] = (uint8_t)(upload_file.total_packet >> 8);
        pbody[2] = (uint8_t)upload_file.current_packet;
        pbody[3] = (uint8_t)(upload_file.current_packet >> 8);
        int32_t len = cm_fs_read(upload_file.fd,pbody+4,UPLOAD_PACKET_SIZE);

        if(len >= 0)
        {
            len+=4;
            txlen = tlv_seal(pf,0x12,tlv_get_seq(),len);
            upload_file.state = upload_send;
        }
        else
        {
            upload_file.retry++;
        }
        break;
    }

    case upload_send:
        plat_send( txbuf, txlen);
        upload_file.send_time = get_runtime(); 
        upload_file.state = upload_wait_ack;
        printf_log(lv2, "file upload packet %d/%d\n", 
                   upload_file.current_packet, upload_file.total_packet);
        break;

    case upload_wait_ack:
        if(time_intval(upload_file.send_time) > 3000){
            upload_file.retry++;
            upload_file.state = upload_send;
            printf_log(lv2, "file upload ack timeout\n");
        }
        break;

    case upload_finished:
        upload_file.result = 1;
        break;
    }

    if(upload_file.retry > UPLOAD_MAX_ERROR)
    {
        upload_file.retry = 0;
        upload_file.state = upload_idle;
        upload_file.result = -2;
    }

    if(upload_file.result != 0)
    {
        if(upload_file.result != -1){

           // free(txbuf);////bug code -----导致内存泄漏-------

            if( NULL != txbuf )
            {
                free(txbuf);////debug -----导致内存泄漏-------
            }

        }
        cm_fs_close(upload_file.fd);
        printf_log(lv1, "file upload %s!\n", upload_file.result == 1 ? "success" : "fail");
        upload_file.state = upload_idle;
    }

#endif

}


/**
 * @brief 上行12ack
 * 
 * @param rxbuf 
 */
void logfile_upload_ack(uint8_t ack)
{
    if(ack == 1)
    {
        if(upload_file.current_packet < upload_file.total_packet){
            upload_file.current_packet++;
            upload_file.state = upload_pack;
        }else{                      //传输完成
            upload_file.state = upload_finished;
        }
    }
}

